package com.nio;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @Author 咕唧
 * @Date 2022/7/5 19:38
 * @Version 1.0
 * nio的directBuffer操作
 */
public class Nio05 {
    public static void main(String[] args) throws Exception {

        //创建一个文件流
        FileInputStream fileInputStream = new FileInputStream("aa.txt");
        //转成nio的方式进行操作,channel可以将数据存放或者从buffer读取出来
        FileChannel fileInputStreamChannel = fileInputStream.getChannel();

        //目标文件
        FileOutputStream fileOutputStream = new FileOutputStream("bb.txt");
        FileChannel fileOutputStreamChannel = fileOutputStream.getChannel();

        //创建bytebuffer,这次是调用的direct方法创建容量空间,数据直接保存在堆外空间，当然byteBuffer对象保存在堆中，但是可以直接通过unsafe操作指定位置的内存，这个位置在buffer父类对象中的address
        //之前的io操作，是操作堆中jvm中的内存，然后由操作系统拷贝到堆外的直接内存当中，操作系统这个时候在吧直接内存当中的数据写到在、磁盘当中，这样数据经过多次拷贝，会有一点点影响效率
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);

        while (true) {
            //不执行清理的话,因为上次循环读取过数据,最终position会等于limit,那下面再read的时候会认为没有空间,会返回0,并不是-1
            byteBuffer.clear();
            int read = fileInputStreamChannel.read(byteBuffer);
            if (read == -1) {
                break;
            }
            //翻转,写入到目标文件
            byteBuffer.flip();
            int write = fileOutputStreamChannel.write(byteBuffer);

        }
        //关闭流
        fileInputStream.close();
        fileOutputStream.close();
    }
}
